package com.barnett.tool;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Environment;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

import com.barnett.http.ThreadPoolUtils;


/**
 * TODO<更新版本>
 * 
 * @author JiangJian
 * @data: 2014-6-4 上午10:33:31
 * @version: V1.0
 */
public class UpdateVersion {
	Context context;
	private final String dirPath = Environment.getExternalStorageDirectory()
			+ File.separator + "UpdateVersion" + File.separator + "version";

	public UpdateVersion(Context context) {
		this.context = context;
	}

	/**
	 * 获取当前程序的版本号
	 * 
	 * @return
	 * @throws Exception
	 */
	public String getVersionName() throws Exception {
		// 获取packagemanager的实例
		PackageManager packageManager = context.getPackageManager();
		// getPackageName()是你当前类的包名，0代表是获取版本信息
		PackageInfo packInfo = packageManager.getPackageInfo(
				context.getPackageName(), 0);
		return packInfo.versionName;
	}

	/**
	 * 弹出对话框通知用户更新程序
	 * 
	 * 弹出对话框的步骤： 1.创建alertDialog的builder. 2.要给builder设置属性, 对话框的内容,样式,按钮
	 * 3.通过builder 创建一个对话框 4.对话框show()出来
	 */
	public void showUpdataDialog(String description, final String url) {
		AlertDialog.Builder builer = new Builder(context);
		builer.setTitle("版本升级");
		builer.setMessage(description);
		// 当点确定按钮时从服务器上下载 新的apk 然后安装
		builer.setPositiveButton("确定", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				Log.i("version", "下载apk,更新");
				downLoadApk(url);
			}
		});
		// 当点取消按钮时进行登录
		builer.setNegativeButton("取消", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
			}
		});
		AlertDialog dialog = builer.create();
		dialog.show();
	}

	public void showForcedUpdataDialog(String description, final String url) {
		AlertDialog.Builder builer = new Builder(context);
		builer.setTitle("版本升级");
		builer.setMessage(description);
		// 当点确定按钮时从服务器上下载 新的apk 然后安装
		builer.setPositiveButton("确定", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				Log.i("version", "下载apk,更新");
				downLoadApk(url);
			}
		});
		// 当点取消按钮时进行登录
		builer.setNegativeButton("取消", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				System.exit(0);
			}
		});
		AlertDialog dialog = builer.create();
		dialog.show();
	}

	/**
	 * 从服务器中下载APK
	 */
	private void downLoadApk(final String url) {
		final ProgressDialog pd; // 进度条对话框
		pd = new ProgressDialog(context);
		pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
		pd.setMessage("正在下载更新");
		pd.show();
		ThreadPoolUtils.execute(new Runnable() {
			@Override
			public void run() {
				Looper.prepare();
				try {
					File file = getFileFromServer(url, pd);
					if (file != null) {
						Thread.sleep(3000);
						installApk(file);
					} else {
						Toast.makeText(context, "更新新版本失败", Toast.LENGTH_SHORT)
								.show();
					}
					pd.dismiss(); // 结束掉进度条对话框
				} catch (Exception e) {
					Toast.makeText(context, "下载新版本失败", Toast.LENGTH_SHORT)
							.show();
					pd.dismiss(); // 结束掉进度条对话框
					e.printStackTrace();
				}
				Looper.loop();
			}
		});
	}

	/**
	 * 从服务器下载apk
	 * 
	 * @param path
	 * @param pd
	 * @return
	 * @throws Exception
	 */
	private File getFileFromServer(String path, ProgressDialog pd)
			throws Exception {
		// 如果相等的话表示当前的sdcard挂载在手机上并且是可用的
		if (Environment.getExternalStorageState().equals(
				Environment.MEDIA_MOUNTED)) {
			URL url = new URL(path);
			SSLContext sc = SSLContext.getInstance("TLS");
			sc.init(null, new TrustManager[] { new MyTrustManager() },
					new SecureRandom());
			HttpsURLConnection
					.setDefaultSSLSocketFactory(sc.getSocketFactory());
			HttpsURLConnection.setDefaultHostnameVerifier(new MyHostnameVerifier());  
			HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();  
			conn.setConnectTimeout(5000);
			// 获取到文件的大小
			pd.setMax(conn.getContentLength());
			InputStream is = conn.getInputStream();

			Log.i("version", dirPath);
			File file = new File(dirPath, "updata.apk");
			try {
				/**
				 * 设置路径，如果没有该路径则创建
				 */
				File dirs = new File(dirPath);
				if (!dirs.exists()) {

					try {
						// 按照指定的路径创建文件夹
						dirs.mkdirs();
					} catch (Exception e) {
						// TODO: handle exception
					}
				}
				dirs = null;
				if (!file.exists())
					file.createNewFile();
			} catch (IOException e) {
				Log.e("IOException", "exception in createNewFile() method");
				return null;
			}
			FileOutputStream fos = new FileOutputStream(file);
			BufferedInputStream bis = new BufferedInputStream(is);
			byte[] buffer = new byte[1024];
			int len;
			int total = 0;
			while ((len = bis.read(buffer)) != -1) {
				fos.write(buffer, 0, len);
				total += len;
				// 获取当前下载量
				pd.setProgress(total);
			}
			fos.close();
			bis.close();
			is.close();
			return file;
		} else {
			return null;
		}
	}

	/**
	 * 安装apk
	 * 
	 * @param file
	 */
	protected void installApk(File file) {
		Intent intent = new Intent();
		// 执行动作
		intent.setAction(Intent.ACTION_VIEW);
		// 执行的数据类型
		intent.setDataAndType(Uri.fromFile(file),
				"application/vnd.android.package-archive");
		context.startActivity(intent);
	}

	private class MyHostnameVerifier implements HostnameVerifier {

		@Override
		public boolean verify(String hostname, SSLSession session) {
			// TODO Auto-generated method stub
			return true;
		}
	}

	private class MyTrustManager implements X509TrustManager {

		@Override
		public void checkClientTrusted(X509Certificate[] chain, String authType)
				throws CertificateException {
			// TODO Auto-generated method stub

		}

		@Override
		public void checkServerTrusted(X509Certificate[] chain, String authType)
				throws CertificateException {
			// TODO Auto-generated method stub

		}

		@Override
		public X509Certificate[] getAcceptedIssuers() {
			// TODO Auto-generated method stub
			return null;
		}
	}
}
